import {CloseCircleOutlined, EyeOutlined} from '@ant-design/icons';
import type {ProColumnType} from '@ant-design/pro-components';
import {
  BetaSchemaForm,
  FooterToolbar,
  PageContainer,
  ProForm,
  ProFormText,
  ProFormTextArea
} from '@ant-design/pro-components';
import {
  AutoComplete,
  Button,
  Card,
  Col,
  Empty,
  Form,
  message,
  Modal,
  Popconfirm,
  Popover,
  Row,
  Space,
  Spin
} from 'antd';
import {FC, useCallback, useState} from 'react';
import {batUpdateFormField, delFormField, fakeSubmitForm, getFormOne, updateFormField} from './service';
import useStyles from './style.style';
import {history, useSearchParams} from "@umijs/max";
import {useRequest} from "@@/exports";
import TypeCascader from '@/components/TypeCascader';
import DragEditTable from './components/DragEditTable'
import {inputTypeEnum} from './constant';
import {delForm} from "@/pages/dynamic-form/list-form/service";
import {debounce} from "@/utils/debounce";
import {getSettingList} from "@/pages/public-setting/service";

interface TableFormDateType {
  key: string;
  id?: string;
  name?: string;
  property?: string;
  input_type?: string;
  options?: string;
  sort?: number
}

type InternalNamePath = (string | number)[];
const fieldLabels = {
  name: '表名',
  type: '类目',
  note: '备注'

};

interface ErrorField {
  name: InternalNamePath;
  errors: string[];
}

const AdvancedForm: FC<Record<string, any>> = () => {
  const {styles} = useStyles();
  const [editing, setEditing] = useState(false)
  const [form] = Form.useForm();
  const [searchParams, setSearchParams] = useSearchParams();
  const [error, setError] = useState<ErrorField[]>([]);
  const [reload, setReload] = useState(false)
  const [currentIptType, setCurrentIptType] = useState('')
  const [editForm] = Form.useForm()
  const [options, setOptions] = useState<any[]>([])

  const formId = searchParams.get('formId');

  const {data: settingInfo} = useRequest(async () => {
    const res = await getSettingList()
    const newVal: any = {}
    Object.keys(res?.data).forEach((key) => {
      try {
        newVal[key] = JSON.parse(res?.data[key]?.value || '')
      } catch (e) {
      }
    })
    newVal.publicFilteringCriteria = newVal?.publicFilteringCriteria?.map((item: any) => ({
      ...item,
      label: `${item.name}(${item.fieldName})`,
      value: item.fieldName
    })) || []

    return {
      data: newVal
    }
  }, {
    onSuccess(data) {
      setOptions(data?.publicFilteringCriteria)
    },
  });

  const {data, loading, refresh: onReload} = useRequest(() => {
    return getFormOne({
      id: formId,
    });
  }, {
    onSuccess(res: any) {
      const values = {
        formHeaderList: res?.formHeaderList?.map((item: any) => ({
          ...item, key: item?.id
        }))?.sort((a: any, b: any) => a.sort - b.sort) || [],
        name: res?.name,
        type: res?.type,
        note: res?.note
      }
      form.setFieldsValue(values)
    },
    refreshDeps: [formId, reload],
    ready: !!formId
  });

  const handleDel: any = useCallback(debounce((item: any) => {
    if (!item?.id) {
      message.error('ID为空')
      return
    }
    Modal.confirm({
      title: `删除表格`,
      content: <div>
        确定删除 <b>{item.name}</b> 表格吗？
        <p style={{color: 'red'}}>删除后不可恢复，请谨慎操作！</p>
      </div>,
      okText: '确认',
      cancelText: '取消',
      onOk: async () => {
        await delForm({
          id: item.id
        })
        message.success('删除成功!')
        history.back()
        return true
      },
    });
  }), [])

  const getErrorInfo = (errors: ErrorField[]) => {
    const errorCount = errors.filter((item) => item.errors.length > 0).length;
    if (!errors || errorCount === 0) {
      return null;
    }
    const scrollToField = (fieldKey: string) => {
      const labelNode = document.querySelector(`label[for="${fieldKey}"]`);
      if (labelNode) {
        labelNode.scrollIntoView(true);
      }
    };
    const errorList = errors.map((err) => {
      if (!err || err.errors.length === 0) {
        return null;
      }
      const key = err.name[0] as 'name' | 'url' | 'owner' | 'approver' | 'dateRange' | 'type';
      return (
        <li key={key} className={styles.errorListItem} onClick={() => scrollToField(key)}>
          <CloseCircleOutlined className={styles.errorIcon}/>
          <div className={styles.errorMessage}>{err.errors[0]}</div>
          <div className={styles.errorField}>{fieldLabels[key]}</div>
        </li>
      );
    });
    return (
      <span className={styles.errorIcon}>
        <Popover
          title="表单校验信息"
          content={errorList}
          overlayClassName={styles.errorPopover}
          trigger="click"
          getPopupContainer={(trigger: HTMLElement) => {
            if (trigger && trigger.parentNode) {
              return trigger.parentNode as HTMLElement;
            }
            return trigger;
          }}
        >
          <CloseCircleOutlined/>
        </Popover>
        {errorCount}
      </span>
    );
  };
  const onFinish = async (values: Record<string, any>) => {
    setError([]);
    try {
      setEditing(true)
      const res = await fakeSubmitForm({
        ...values,
        id: formId,
        type: Array.isArray(values.type) ? (values.type?.[values.type?.length - 1] || '') : values.type
      });
      // console.log(res?.data?.id);
      if (res?.code === 0) {
        message.success('提交成功');
        setEditing(false)
        if (res?.data?.id) {
          setSearchParams({
            formId: res?.data?.id
          })
          setReload(!reload)
        }
      } else {
        message.warning(res?.msg || '提交失败');
        setEditing(false)
      }

    } catch {
      // console.log
      setEditing(false)
    }
  };
  const onFinishFailed = (errorInfo: any) => {
    setError(errorInfo.errorFields);
  };
  const columns: ProColumnType<TableFormDateType>[] = [
    {
      title: '序号',
      dataIndex: 'sort',
      key: 'sort',
      tooltip: '输入整数，值越小越靠前',
      width: 100,
      editable: false,
      valueType: 'digit',
      formItemProps: () => {
        return {
          rules: [{required: true, message: '此项为必填项'}],
        };
      },
      initialValue: form.getFieldsValue()?.formHeaderList?.length + 1,
      fieldProps: {
        step: '1',
      }
    },
    {
      title: '属性名称',
      dataIndex: 'property',
      tooltip: '字段名的中文描述',
      fieldProps: {
        placeholder: '请输入属性名'
      },
      formItemProps: () => {
        return {
          rules: [{required: true, message: '此项为必填项'}],
        };
      },
      key: 'property',
      // width: '20%',
    },
    // {
    //   title: '类型',
    //   dataIndex: 'propertyType',
    //   key: 'propertyType',
    //   initialValue: 'text',
    //   valueType: 'select',
    //   valueEnum: propertyTypeEnum,
    //   hideInForm: true,
    //   render(text: any) {
    //     return propertyTypeEnum[text]?.text
    //   }
    // },
    {
      title: '输入方式',
      dataIndex: 'inputType',
      key: 'inputType',
      fieldProps: {
        onChange(val) {
          setCurrentIptType(val as any)
        }
      },
      formItemProps: () => {
        return {
          rules: [{required: true, message: '此项为必填项'}],
        };
      },
      initialValue: 'input',
      valueType: 'select',
      valueEnum: inputTypeEnum,
      render(text: any) {
        return inputTypeEnum[text]?.text
      }
    },
    {
      title: '字段名',
      dataIndex: 'name',
      tooltip: '表头字段名称，必须为唯一值',
      fieldProps: {
        placeholder: '请输入字段名',
        // disabled: true,
      },
      initialValue: new Date().getTime().toString(36) + Math.random().toString(36).substr(2, 9),
      formItemProps: () => {
        return {
          rules: [{required: true, message: '此项为必填项'}],
        };
      },
      renderFormItem() {
        return <AutoComplete
          options={options}
          // style={{ width: 200 }}
          // onSelect={onSelect}
          onSearch={(text) => {
            console.log('settingInfo', settingInfo)
            const newOptions = settingInfo?.publicFilteringCriteria.filter((item: any) => item.value?.indexOf(text) !== -1)
            console.log('newOptions', newOptions)
            setOptions(newOptions)
          }}
          placeholder="请输入字段名"
        />
      }

    },
    /**
     * 此处对某个字段定义排序规则，前端表格层实现排序
     */
    {
      title: '支持排序',
      dataIndex: 'canSort',
      valueType: 'select',
      initialValue: 'not',
      valueEnum: {
        asc: {text: '升序'},
        desc: {text: '降序'},
        not: {text: '不支持'},
      },
      render(dom, record: any) {
        return {
          asc: {text: '升序'},
          desc: {text: '降序'},
          not: {text: '不支持'},
        }[record?.canSort]?.text || '-'
      }
    },
    {
      title: '选择项',
      dataIndex: 'options',
      key: 'options',
      // width: '40%',
      hideInForm: currentIptType === '' ? true : !['select', 'radio'].includes(currentIptType),
      fieldProps: {
        placeholder: 'eg: A,B,C(没有可不填)',
        multiple: true,
        mode: 'tags',
      },
      tooltip: 'eg: A,B,C(没有可不填)',
      // editable: (text, record, index) => {
      //   return record.input_type === 'select';
      // },
      valueType: 'select',
      render(dom) {
        return dom || '-'
      }
    },
    {
      title: '操作',
      key: 'action',
      valueType: 'option',
      render: (_, record: TableFormDateType,) => {

        return <Space>
          <BetaSchemaForm<any>
            key="primary"
            form={editForm}
            layoutType={'ModalForm'}
            onFinish={async (values) => {
              // console.log(values);
              const hide = message.loading('正在保存');
              try {
                let options = values?.options

                if (Array.isArray(options)) {
                  options = options?.join(',')
                }
                const res = await updateFormField({
                  formType: formId,
                  id: record?.id,
                  ...values,
                  options
                })
                // console.log('res', res);
                if (res?.code === 0) {
                  hide();
                  message.success('保存成功');
                  onReload?.()
                  return true
                } else {
                  message.error('保存失败请重试！');
                  return false
                }
              } catch (e) {
                console.log(e);
                hide();
                message.error('保存失败请重试！');
                return false
              }
            }}
            modalProps={{
              destroyOnClose: true,
              title: "编辑列",
              width: "500px",
            }}
            trigger={<a
              key="eidit"
              onClick={() => {
                const initialVal = JSON.parse(JSON.stringify(record));
                try {
                  initialVal.options = initialVal.options?.split(',') || []
                } catch (e) {
                }
                editForm.setFieldsValue({
                  ...initialVal
                })
              }}
            >
              编辑
            </a>}
            columns={columns as any}
          />
          <Popconfirm
            title="删除列"
            description={`确认删除 ${record?.property} 列?`}
            onConfirm={async () => {
              const hide = message.loading('正在删除');
              try {
                const res = await delFormField({
                  id: record?.id
                })
                // console.log('res', res);
                if (res?.code === 0) {
                  hide();
                  message.success('删除成功');
                  onReload?.()
                  return true
                } else {
                  message.error('删除失败请重试！');
                  return false
                }
              } catch (e) {
                console.log(e);
                hide();
                message.error('删除失败请重试！');
                return false
              }

            }}
            onCancel={() => {

            }}
            okText="是"
            cancelText="否"
          >
            <a key={'del'}>删除</a>
          </Popconfirm>
        </Space>
      },
    },
  ];

  return (
    <Spin spinning={loading}>
      <ProForm
        layout="vertical"
        loading={editing}
        form={form}
        // hideRequiredMark
        submitter={{
          render: (props, dom) => {
            return (
              <FooterToolbar>
                {getErrorInfo(error)}
                {data && <Button danger onClick={() => {
                  handleDel(data)
                }}>删除</Button>}
                {dom}
              </FooterToolbar>
            );
          },
        }}
        initialValues={{
          formHeaderList: [],
        }}
        onFinish={onFinish}
        onFinishFailed={onFinishFailed}
      >
        <PageContainer content="支持创建和设计表单字段，适合需要动态配置的场景。">
          <Card title="表单信息" className={styles.card} bordered={false}>
            <Row gutter={16}>
              <Col lg={6} md={12} sm={24}>
                <ProFormText
                  label={'表名'}
                  name="name"
                  rules={[
                    {
                      required: true,
                      message: '请输入表名',
                    },
                  ]}
                  placeholder="请输入表名"
                />
              </Col>
              <Col lg={6} md={12} sm={24}>
                <Form.Item label={'类目'} name="type">
                  <TypeCascader
                    formId={formId}
                  />
                </Form.Item>
              </Col>
              <Col lg={24} md={24} sm={24}
              >
                <ProFormTextArea
                  label={'备注'}
                  name="note"
                  fieldProps={{maxLength: 200}}
                  // rules={[
                  //   {
                  //     required: true,
                  //     message: '请输入备注',
                  //   },
                  // ]}
                  placeholder="请输入备注"
                />
              </Col>
            </Row>
          </Card>

          <Card title="表头信息" bordered={false} extra={<Button icon={<EyeOutlined/>} onClick={() => {
            history.push(`/product?formId=${data.id}&type=${data.type}`);
          }}>查看数据</Button>}>
            {formId ? <ProForm.Item name="formHeaderList">
              <DragEditTable
                onReload={onReload}
                form={form}
                columns={columns}
                formType={formId}
                scroll={{x: 'max-content'}}
                onDragSuccess={async (newData: any) => {
                  const hide = message.loading('正在修改列表排序');
                  try {
                    const res = await batUpdateFormField(newData?.map((item: any) => ({
                      id: item?.id,
                      sort: item?.sort
                    })))
                    // console.log('res', res);
                    if (res?.code === 0) {
                      hide();
                      message.success('修改列表排序成功');
                      onReload?.()
                      return true
                    } else {
                      message.error('修改失败请重试！');
                      return false
                    }
                  } catch (e) {
                    console.log(e);
                    hide();
                    message.error('修改失败请重试！');
                    return false
                  }
                }}
              />
            </ProForm.Item> : <Empty description='请提交后设计字段'></Empty>}
          </Card>
        </PageContainer>
      </ProForm>
    </Spin>
  );
};
export default AdvancedForm;
